#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <curl/curl.h>
#include "../thirdparty/cJSON.h"
#include "../thirdparty/log.h"
#include "ota_http_curl.h"


/*http响应的回调函数*/
static size_t ota_http_curl_write_callback(char* data,size_t size,size_t nmemb,void* userp)
{
    /*1.强转合适的指针类型*/
    response_t* respon = (response_t*)userp;
    /*2.申请存放响应信息的内存*/
    size_t total_size = size * nmemb;
    respon->response_str = (char*)malloc(sizeof(char) * (total_size + 1));
    if (respon->response_str == NULL)
    {
        log_error("str mem malloc fail\n");
        return -1;
    }
    /*将响应数据存放进容器并更新响应长度*/
    memcpy(respon->response_str,data,total_size);
    respon->response_str[total_size] = '\0';
    respon->response_len = total_size;

    return total_size;    
}
/**
 * @brief curl客户端向http服务端发起请求  访问服务端的版本信息
 *
 * @param url http服务端路径
 * @param response http响应结构体
 * @return version_t* 服务端的版本信息
 */
version_t* ota_http_curl_getversion(char *url)
{
    /*定义存放http响应信息的结构体指针*/
    response_t *response_p;
    response_p = (response_t *)malloc(sizeof(response_t) * 1);
    if (response_p == NULL)
    {
        log_error("response_t mem malloc fail\n");
        return NULL;
    }
    /*1.初始化curl客户端并接收客户端句柄*/
    CURL *curl = curl_easy_init();
    /*2.向客户端传入参数*/
    /*2.1传入http服务端的url*/
    curl_easy_setopt(curl, CURLOPT_URL, url);
    /*2.2传入http响应的回调函数*/
    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, ota_http_curl_write_callback);
    /*2.3传入接收http响应的容器*/
    curl_easy_setopt(curl,CURLOPT_WRITEDATA,response_p);
    /*3.发起http请求*/
    CURLcode res = curl_easy_perform(curl);
    /*4.若无响应表示http请求失败*/
    if (res != CURLE_OK)
    {
        log_error("http request fail\n");
        curl_easy_cleanup(curl);
        return NULL;
    }
    /*5.清理客户端*/
    curl_easy_cleanup(curl);
    /*6.解析响应的json字符串得到版本信息*/
    cJSON* object = cJSON_Parse(response_p->response_str);
    cJSON* major_item = cJSON_GetObjectItem(object,"major");
    cJSON* minor_item = cJSON_GetObjectItem(object,"minor");
    cJSON* patch_item = cJSON_GetObjectItem(object,"patch");
    cJSON* sha1_item = cJSON_GetObjectItem(object,"sha1");
    int major = major_item->valueint;
    int minor = minor_item->valueint;
    int patch = patch_item->valueint;
    char* sha1 = sha1_item->valuestring;
    // log_info("cjson_valuestring:%s\n",sha1_item->valuestring);
    /*7.定义版本信息结构体获取版本信息和sha1码*/
    version_t* version_msg;
    version_msg = (version_t*)malloc(sizeof(version_t) * 1);
    version_msg->sha1 = (char*)malloc(sizeof(char) * strlen(sha1));
    if (version_msg == NULL || version_msg->sha1 == NULL)
    {
        log_error("version_t mem malloc fail\n");

        return NULL;
    }
    version_msg->major = major;
    version_msg->minor = minor;
    version_msg->patch = patch;
    memcpy(version_msg->sha1,sha1,strlen(sha1));
    version_msg->sha1[strlen(sha1)] = '\0';
    // log_info("memcpy_string:%s\n",version_msg->sha1);
    log_info("get version information success\n");
    /*8.释放cjson占用的内存资源*/
    cJSON_Delete(object);
    return version_msg;
}

/**
 * @brief curl客户端访问http客户端   下载服务端的文件
 * 
 * @param url http服务端路径
 * @param filename 文件名[包含路径]
 * @return int 成功返回0 失败返回-1
 */
int ota_http_curl_download(char *url, char *filename)
{
    /*1.初始化curl客户端*/
    CURL* curl = curl_easy_init();
    /*2.打开文件*/
    FILE* file = fopen(filename,"wb");
    if (file == NULL)
    {
        log_error("file open fail\n");
        curl_easy_cleanup(curl);
        return -1;
    }
    /*3.传入参数*/
    curl_easy_setopt(curl,CURLOPT_URL,url); //服务端路径
    curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,fwrite);    //传入回调函数
    curl_easy_setopt(curl,CURLOPT_WRITEDATA,file);          //传入装载数据的容器
    /*4.访问服务端*/
    CURLcode res = curl_easy_perform(curl);
    if (res != CURLE_OK)
    {
        log_error("http request fail\n");
    }
    else
    {
        log_info("http request sucess\n");
    }
    /*5.清理客户端*/
    curl_easy_cleanup(curl);
    /*6.关闭文件*/
    fclose(file);

    return res == CURLE_OK ? 0 : -1;
}
